#include "common.h"
#include "syscall.h"
#include "spinlock.h"
#include "proc.h"
#include "riscv.h"

// 获取第n个系统调用参数
static uint64 argraw(int n) {
    struct proc *p = getproc();
    switch(n) {
        case 0:
            return p->trapframe->a0;
        case 1:
            return p->trapframe->a1;
        case 2:
            return p->trapframe->a2;
        case 3:
            return p->trapframe->a3;
        case 4:
            return p->trapframe->a4;
        case 5:
            return p->trapframe->a5;
    }
    panic("argraw: 没有该参数！\n");
    return -1;
}
// 将第n个系统调用整数参数存储到指定变量中
void argint(int n, int *ip) {
    *ip = argraw(n);
}
// 进程退出系统调用
uint64 sys_exit(void) {
    int n;
    // 获取第0个系统调用参数（进程退出状态）
    argint(0, &n);
    exit(n);
    // 一般不会执行到这
    return 0;
}
// 系统调用函数指针数组
static uint64 (*syscalls[])(void) = {
    [SYS_exit]    sys_exit
};
// 系统调用处理函数
void syscall(void) {
    struct proc *p = getproc();
    int num = p->trapframe->a7;    // 系统调用号（约定存储在a7中）
    // 系统调用号合法且存在对应的处理函数
    if(num > 0 && num < (sizeof(syscalls)/sizeof(syscalls[0])) && syscalls[num]) {
        // 调用对用的系统调用函数并将结果存储到a0中（约定）
        p->trapframe->a0 = syscalls[num]();
    } else {
        printf("syscall: 未知系统调用号 pid=%d, pname=%s, num=%d\n", p->pid, p->name, num);
        p->trapframe->a0 = -1;
    }
}